package cn.leaf.config;

import cn.leaf.constants.Constant;
import cn.leaf.entity.Message;
import cn.leaf.util.JacksonUtil;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

/**
 * description: 消息队列监听，消费消息
 *
 * @author Cyril
 * @version v1.0.0
 * @since 2021-05-20 22:24:40
 */
@Slf4j
@Component
public class ConsumerListener {

    @RabbitListener(queues = {Constant.MESSAGE_DIRECT_QUEUE})
    public void msgConsumer(String msg, Channel channel,
                            CorrelationData correlationData,
                            @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {
        try {
            String msgId = correlationData.getId();

            Message message = JacksonUtil.json2Bean(msg, Message.class);
            log.info("消息实体内容 ---> {}", message);

            // 1. TODO 业务处理 保证消息幂等性

            // 2. 模拟异常 消息没有正常消费被打入死信队列
//            int result = 1/0;

            // 确认消息已经成功消费
            channel.basicAck(tag, false);
            log.info("消息被成功消费了......");
        } catch (Exception ex) {
            log.error("消息消费失败，进入死信队列......");
            // arg1: 消息的tag arg2：是否多条处理 arg3：是否重发（false：打入死信队列，如若使用true不加try...catch使程序进入死循环）
            channel.basicNack(tag, false, false);
        }
    }
}
